#include <QQueue>
#include <QMetaObject>
#include <QMetaProperty>
#include <QDebug>
#include <QPair>
#include "ShortCut.h"
#include "config/ConfigDataModel.h"
#include "config/items/ItemShortcut.h"
#include "global.h"

static Qt::KeyboardModifiers kMRecorder(Qt::NoModifier);
static int kCRecorder = 0;

void ShortCut::pressed(Qt::Key key)
{
    if (isPressingShortcutWidget)
        return;
    pressing = true;
    switch (key)
    {
    case Qt::Key::Key_Control:
        kMRecorder.setFlag(Qt::KeyboardModifier::ControlModifier);
        break;
    case Qt::Key::Key_Alt:
        kMRecorder.setFlag(Qt::KeyboardModifier::AltModifier);
        break;
    case Qt::Key::Key_Shift:
        kMRecorder.setFlag(Qt::KeyboardModifier::ShiftModifier);
        break;
    case Qt::Key::Key_Meta:
        kMRecorder.setFlag(Qt::KeyboardModifier::MetaModifier);
        break;
    default:
        kCRecorder = key;
    }
}

void ShortCut::released(Qt::Key key)
{
    Q_UNUSED(key)
    if (pressing)
    {
        pressing = false;
        QKeySequence shortcut = int(kMRecorder) + kCRecorder;
        kMRecorder = Qt::NoModifier;
        kCRecorder = 0;

        for (auto item : items)
        {
            QPair<bool, QKeySequence> res = item->get();
            if (res.first && shortcut.matches(res.second) == QKeySequence::ExactMatch)
            {
                item->invoke();
            }
        }
    }
}


ShortCut::ShortCut(ConfigDataModel *data)
{
    m_data = data;

    QQueue<ConfigDataModel*> models;
    models.enqueue(data);

    while (!models.isEmpty())
    {
        ConfigDataModel *model = models.dequeue();
        const QMetaObject *obj = model->metaObject();
        for (int i = obj->propertyOffset(); i < obj->propertyCount(); i++)
        {
            QMetaProperty property = obj->property(i);
            if (property.read(model).canConvert<ItemShortcut*>())
            {
                items.insert(property.read(model).value<ItemShortcut*>());
            }
            else if (property.read(model).canConvert<ConfigDataModel*>())
            {
                models.enqueue(property.read(model).value<ConfigDataModel*>());
            }
        }
    }
}





